package cn.sccl.common.cas;

import cn.sccl.common.web.BaseController;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections.MapUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户登录省份验证：外调新版的认证系统·
 *
 * @author xiaoyan
 * @version 创建时间：2017年8月7日 上午10:15:40
 */

@RestController
@RequestMapping(value = "/dirms/cas")
public class CasLoginCallBackController extends BaseController {

    // 设置应用系统的AppID，每个应用都不同，你要先去申请注册
    @Value("${cas.appId}")
    private String appId;
    // 设置应用系统的appSecret，每个应用都不同，你要先去申请注册
    @Value("${cas.appSecret}")
    private String appSecret;
    //前端的地址
    @Value("${cas.frontHost}")
    private String frontHost;

    // 服务器地址
    @Value("${cas.server}")
    private String server;

    // 检查token的地址
    @Value("${cas.check_token}")
    private String check_token;

    // 获取用户信息的地址
    @Value("${cas.get_user_info}")
    private String get_user_info;

	/*
     *
	 *
	 */

    @RequestMapping(value = "/callback")
    public void callback(@RequestParam("token") String token, @RequestParam("state") String state, HttpServletResponse response) throws IOException {
        response.sendRedirect(frontHost+(frontHost.endsWith("/")?"":"/")+"#/?token=" + token + "&" + "state=" + state);
    }

    @ResponseBody
    @RequestMapping(value = "/cas_getUser",method = {RequestMethod.POST})
    public Map<String, String> cas_getUser(@RequestBody Map<String,Object> params,HttpServletRequest request) throws ParseException, IOException {
        String token = MapUtils.getString(params,"token","");
        String useip = getIpAddress(request);
        String url = server + check_token;
        Map<String, String> userInfo  =   new HashMap<String,String>();
        HttpClient httpClient = GetHttpClient.getHttpClient();
        String json = jsonMethod(token, useip, appId, appSecret);
        HttpPost post = new HttpPost(url);
        StringEntity postingString = new StringEntity(json);// json传递
        post.setEntity(postingString);
        post.setHeader("Content-type", "application/json");
        HttpResponse response = httpClient.execute(post);
        String content = EntityUtils.toString(response.getEntity());
        if(content != null || "".equals(content)){
            Map<String, String> map = JSON.parseObject(content, Map.class);
            String openid = map.get("openid");
            String accessToken = map.get("access_token");
            if(openid != null || "".equals(openid)){
                userInfo = getUserInfo(accessToken,openid);
                System.out.println("userInfo=="+userInfo);
            }
        }
        post.releaseConnection();
        System.out.println("postToken=="+content);
        return userInfo;

    }

    /*
     * 第三步：通过access_token和openid获取个人信息
     */
    private Map<String, String> getUserInfo(String aaccessToken, String openid) throws ParseException, IOException {
        Map<String, String> infoMap = new HashMap<String,String>();
        //HttpClient httpClient = new DefaultHttpClient();
        HttpClient httpClient = GetHttpClient.getHttpClient();
        HttpPost post = new HttpPost(server + get_user_info);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("access_token", aaccessToken);
        jsonObject.put("openid", openid);
        String jsonstr = JSONObject.toJSONString(jsonObject);
        StringEntity postingString = new StringEntity(jsonstr);// jsonstr传递
        post.setEntity(postingString);
        post.setHeader("Content-type", "application/json");
        HttpResponse response = httpClient.execute(post);
        String content = EntityUtils.toString(response.getEntity());
        System.out.println("getUserInfocontent=="+content);
        if(content != null || "".equals(content)){
            ////获取用户信息
            Map<String, String> map = JSON.parseObject(content, Map.class);
            String username = map.get("username");
            String name = map.get("name");
            String group = map.get("group");
            String n_openid = map.get("openid");
            String wx_openid = map.get("wx_openid");
//			BeanUtils.copyProperties(source, target);
            if(username != null || "".equals(username)){
                infoMap.put("username",username);
                infoMap.put("name",name);
                infoMap.put("group",group);
                infoMap.put("openid",n_openid);
                infoMap.put("wx_openid",wx_openid);
            }
        }
        post.releaseConnection();
        return infoMap;
    }

    /*
     * 参数名 是否必须 类型 说明
     *  token 是 string
     *  上一步获取的token
     *  appid 是 string appid appsecret
     * 是 string app密钥 userip 是 string ip地址
     */
    public static String jsonMethod(String token, String userip, String appid, String appsecret) {
        System.out.println("userip==" + userip);
        String localIp = "";
        // 当在服务器上本地测试时，用户访问ip会变成10.0.2.2，而中央认证将获取到本地服务器ip，故需要手动替换
        if ("10.0.2.2".equals(userip)) {
            localIp = "172.27.15.28";
        } else {
            localIp = userip;
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("token", token);
        jsonObject.put("appid", appid);
        jsonObject.put("appsecret", appsecret);
        jsonObject.put("userip", localIp);
        String jsonstr = JSONObject.toJSONString(jsonObject);
        System.out.println("jsonMethod的jsonstr+++++====" + jsonstr);
        return jsonstr;
    }

    @ResponseBody
    @RequestMapping(value = "/getAppInfo")
    public Object getAppInfo(HttpServletRequest request) {
        Map<String, Object> res = new HashMap();
        res.put("appId", appId );
        res.put("appSecret", appSecret );
        return res;
    }

    @ResponseBody
    @RequestMapping(value = "/getIP")
    public Object getIP(HttpServletRequest request) {
        Map<String, Object> res = new HashMap();
        res.put("ip", getIpAddress(request));
        return res;
    }


    public static String getIpAddress(HttpServletRequest request) {

        String ip = "";
        ip = request.getHeader("x-forwarded-for");

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Forwarded-For");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }

        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        if (null != ip && ip.indexOf(',') != -1) {
            //如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串 IP 值
            //取X-Forwarded-For中第一个非unknown的有效IP字符串
            //如：X-Forwarded-For：192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100
            //用户真实IP为： 192.168.1.110
            //注意:当访问地址为 localhost 时 地址格式为 0:0:0:0:0:0:1
            String[] ips = ip.split(",");
            for (int i = 0; i < ips.length; i++) {
                if (null != ips[i] && !"unknown".equalsIgnoreCase(ips[i])) {
                    ip = ips[i];
                    break;
                }
            }
            if ("0:0:0:0:0:0:1".equals(ip)) {
                ip = "127.0.0.1";
//                System.out.println("由于客户端访问地址使用 localhost，获取客户端真实IP地址错误，请使用IP方式访问");
            }
        }

        if ("unknown".equalsIgnoreCase(ip)) {
//            System.out.println("由于客户端通过Squid反向代理软件访问，获取客户端真实IP地址错误，请更改squid.conf配置文件forwarded_for项默认是为on解决");
            ip = "unknown";
        }
        return ip;
    }
}
